﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace terrariumGame
{
    public class Sprite
    {
        Texture2D texture; // текстура        
        private Rectangle[] animationRectangles;// прямоугольники указывающие кадры из текстуры для анимации.
        private Vector2 position;// позиция на экране
        private Rectangle sizeTextureRectangle; // размер картинки (ширина длина)
        private Color color; // цвет
        private float rotation; //угол поворота
        private Vector2 origin; // центральная точка
        private SpriteEffects effect; //эффект прорисовки
        private float layerDepth; // прозрачность от 0 до 1(полностью прозрачный)
        private float scale; // зумер
        private SpriteBatch spriteBatch;

        private int currentFrame; //текущий кадр анимации
        private int lastFrame; //последний кадр анимации
        private int firstFrame; //первый кадр анимации        
        //private int widthSplit; //ширина текстурки покуда вырезать для анимации
        //private int heightSplit; //высота будущей анимации.
        private bool isLoopAnimation; // вкл или выкл повтор анимации
        private bool isEnabledAnimation; // вкл или выкл анимацию вовсе.
        private float speedAnimation; //скорость анимации
        private float valueIntervalTime; // текущее значенее времени 
        private float valueMaxIntervalTime; // максимальное значение времени, после которого амимация переходит на следущий кадр. 

        private bool isLastFrame;
        private bool isStartedAnimation;

        //инициализация спрайта
        public Sprite(SpriteBatch sb, Texture2D texture, int sizeXy, Color color, float rotation, Vector2 origin, float scale, SpriteEffects effect, float layerDepth, bool isEnabledAnimation)
        {

            spriteBatch = sb;
            this.texture = texture;
            animationRectangles = new Rectangle[1];
            animationRectangles[0] = new Rectangle(0, 0, sizeXy, sizeXy);
            this.color = color;
            this.scale = scale;
            this.effect = effect;
            this.layerDepth = layerDepth;
            this.rotation = rotation;
            this.origin = origin;
            this.isEnabledAnimation = isEnabledAnimation;


        }
        public Sprite(SpriteBatch sb, Texture2D texture, bool isEnabledAnimation)
        {
            spriteBatch = sb;
            this.isEnabledAnimation = isEnabledAnimation;
            this.texture = texture;
            animationRectangles = new Rectangle[1];
            animationRectangles[0] = new Rectangle(0, 0, 64, 64);

            color = Color.White;
            rotation = 0;
            origin = new Vector2();
            effect = new SpriteEffects();
            layerDepth = 0;
            scale = 1;

        }

        //инициализация анимации
        public void InitAnimation(int tileX,int tileY, int lastTileX,int lastTileY,int widthSplit, int heightSplit,bool isLoopAnimation, float speedAnimation)
        {

            //tilexy, стартовый фрейм в массиве тайлов. lasttilexy - последний фрейм в массиве тайлов
            isEnabledAnimation = true;
            isStartedAnimation = true;
            this.isLoopAnimation = isLoopAnimation;
            this.speedAnimation = speedAnimation;
            valueMaxIntervalTime = 100;
            int countFrameHorizontal;
            int countFrameVertical;
            int countFrame;

            if ((tileX == 0) && (tileY == 0) && (lastTileX == 0) && (lastTileY == 0))
            {
                countFrameHorizontal = texture.Bounds.Width / widthSplit;
                countFrameVertical = +texture.Bounds.Height / heightSplit; ;                 
            }
            else
            {
                countFrameHorizontal = lastTileX-tileX+1;
                countFrameVertical = lastTileY-tileY+1;
            }
            
            countFrame = countFrameHorizontal * countFrameVertical;   

            firstFrame = 0;
            lastFrame = countFrame;
            currentFrame = 0;

            animationRectangles = new Rectangle[countFrame];

            int num = 0;
            for (int j = tileY; j < countFrameVertical+tileY; j++)
            {
                for (int i = tileX; i < countFrameHorizontal+tileX; i++)
                {

                    animationRectangles[num] = new Rectangle(i*widthSplit, j*heightSplit, widthSplit, heightSplit);
                    num++;
                }

            }

        }
        public void InitAnimation(int widthSplit, int heightSplit, bool isLoopAnimation, float speedAnimation)
        {
            InitAnimation(0, 0, 0, 0, widthSplit, heightSplit, isLoopAnimation,
                          speedAnimation);
        }
        
        //методы для работы с кадрами
        public void StopAnimation()
        {
            isStartedAnimation = false;
        }
        public void StartAnimation()
        {
            isStartedAnimation= true;
        }
        public void NextFrame()
        {
            if(currentFrame<lastFrame) currentFrame += 1;
        }
        public void LastFrame()
        {
            currentFrame = lastFrame;
        }
        public void FirstFrame()
        {
            currentFrame = firstFrame;
        }
        public void PreviousFrame()
        {
            if (currentFrame > 0) currentFrame--;
        }
        public void UpdateAnimation()
        {
            if ((isEnabledAnimation)&&(isStartedAnimation))
            {
                valueIntervalTime += speedAnimation;
                if (valueIntervalTime>=valueMaxIntervalTime)
                {
                    valueIntervalTime = 0;
                    if (currentFrame < lastFrame-1)
                    {
                        currentFrame += 1;
                    }
                    else
                    {
                        if (isLoopAnimation)
                        {
                            currentFrame = 0;
                        }
                        else
                        {
                            isLastFrame = true;
                            StopAnimation();
                        }
                    }

                }

            }
        }
        
        //методы для работы с прорисовкой
        public void Draw()
        {

            spriteBatch.Draw(texture, position, animationRectangles[currentFrame], color, (float)(rotation * 180 / Math.PI), origin, scale, effect, layerDepth);
        }
        public void Draw(Vector2 position)
        {
            spriteBatch.Draw(texture, position, sizeTextureRectangle, color, (float)(rotation * 180 / Math.PI), origin, scale, effect, layerDepth);
        } // прорисовка спрайта
        public void DrawTiles(int startPosX,int startPosY, int countX, int countY)
        {
            
            for (int x = startPosX; x < countX; x++)
            {
                for (int y = startPosY; y < countY; y++)
                {
                    Vector2 pos = new Vector2(x * animationRectangles[0].Width, y * animationRectangles[0].Height);
                    spriteBatch.Draw(texture, pos + position, animationRectangles[currentFrame], color, (float)(rotation * 180 / Math.PI), origin, scale, effect, layerDepth);
                }
            }
        }
        public void DrawTiles(int countX, int countY)
        {
            DrawTiles(0,0,countX,countY);
        } //прорисовка текстурки тайлами
        public void DrawTilesFullScreen()
        {
            int width = spriteBatch.GraphicsDevice.Adapter.CurrentDisplayMode.Width;
            int height = spriteBatch.GraphicsDevice.Adapter.CurrentDisplayMode.Height;
            DrawTiles(-1, -1, width / animationRectangles[currentFrame].Width + 1, height / animationRectangles[currentFrame].Height + 1);
        }  //прорисовка тайлов на всю ширину\длину экрана
        
        //методы для вращения изобржений
        public void Rotate(float rotate)
        {
            this.rotation = rotate;
        } // сет угол поворота спрайта
        public void Turn(float rotate)
        {
            this.rotation += rotate;
        }  //  адд угол поворота спрайта

        //сеттеры
        public void SetNewTexture(Texture2D newTexture)
        {
            this.texture = newTexture;
        } 
        public void SetPosition(Vector2 positionSprite)
        {
            this.position = positionSprite;
        } 
        public void SetPosition(float x, float y)
        {
            this.position = new Vector2(x, y);
        }        
        public void SetSize(int width, int height)
        {
            sizeTextureRectangle = new Rectangle(0, 0, width, height);

        }        
        public void SetColor(Color colorSprite)
        {
            this.color = colorSprite;
        }
        public void SetOrigin(Vector2 originPoint)
        {
            this.origin = originPoint;
        }
        public void SetScale(float scale)
        {
            this.scale = scale;
        }
        public void SetSpriteEffect(SpriteEffects spriteEffect)
        {
            this.effect = spriteEffect;
        }
        public void SetLayerDepth(float depth)
        {
            this.layerDepth = depth;
        }
        
        //аддеры
        public void AddLayerDepth(float depth)
        {
            if((depth>=0)&&(depth<=1)) layerDepth += depth;
        }
        public void AddPosition(float x, float y)
        {
            position.X += x;
            position.Y += y;
        }
        public void AddScale(float add)
        {
            scale += add;
        }
        public void AddSize(int width, int height)
        {
            sizeTextureRectangle.Width += width;
            sizeTextureRectangle.Height += height;
        }
        
        //геттеры
        public Texture2D GetTexture()
        {
            return texture;
        }
        public Vector2 GetPosition()
        {
            return position;
        }
        public Rectangle GetSize()
        {
            return sizeTextureRectangle;
        }
        public Color GetColor()
        {
            return color;
        }
        public Vector2 GetOrigin()
        {
            return origin;
        }
        public float GetScale()
        {
            return scale;
        }
        public SpriteEffects GetSpriteEffects()
        {
            return effect;
        }
        public float GetLayerDepth()
        {            
            return layerDepth;
        }
    }
}
